#ifndef FILE_MANAGER_H
#define FILE_MANAGER_H

#include "escal.h"
#include <QBitArray>
#include <QByteArray>
#include <QList>
#include <QMutex>
#include <QDir>
#include <QFile>
#include <QWaitCondition>
#include <QThread>

class FileManager:public QThread{
    Q_OBJECT
public:
    FileManager(QString folderName, QString fileName, QObject *parent = 0);
    ~FileManager();
    bool isNew() const { return newFile ; };
    void checkDigest();
    bool initNewFile(const qint64 &fileSize ,bool acceptRange);
    int read(int pieceIndex, qint64 offset, int length);
         bool write(int &pieceIndex, qint64 &offset, const QByteArray &data);
            int getPieceNum();
    qint64 getFileSize(){ return fileSize; };
    qint64 getFinishedSize(){ return finishedSize; };
    int getUndonePieceNum();
    bool isAcceptRange();
    void setAcceptRange();
    bool hasError() { return error; };
    int getPiece(int formerPieceIndex=-1);
    void releasePiece(int pieceIndex);
signals:
    void fileIsInitialized();
    void fileIsFinished();
    void progressForward();
protected:
    QByteArray readBlock(int pieceIndex, qint64 offset, int length);
    bool writeBlock(int pieceIndex, qint64 offset, const QByteArray &data);
    bool setPaths(const QString &folderName, const QString &fileName);
    void cleanUp();
    void run();
    void syncDigest();
    bool loadDigest();
private:
    bool newFile;
    bool quit;
    bool acceptRange;
    bool error;
    bool progressForwarded;
    qint64 fileSize;
    qint64 finishedSize;
    int pieceNum;
    QString folderName;
    QString fileName;
    QString dateString;
    // the file to restore the file info 
    QString digestFileName;
    QFile file;
    QFile digestFile;
    QDir dir;
    struct WriteRequest {
        int pieceIndex;
        qint64 offset;
        QByteArray data;
    };
    struct ReadRequest {
        int pieceIndex;
        qint64 offset;
        int length;
        int id;
    };
    
    mutable QWaitCondition cond;
    QMutex mutex;
    QBitArray piecesWorking;
    QBitArray piecesDone;
    QList<WriteRequest> writeRequests;
    QList<ReadRequest> readRequests;
};

#endif /* FILE_MANAGER_H */
